<?php
/**
 * Summary
 * 
 * Adaptador para cache basado en archivos. Puede ser usando en conjunto a un 
 * disco ram, de esta forma guardara los registros en memoria.
 * 
 * Todo: Falta crear el colector de basura para hacer expirar los registros
 */

namespace SubMemory\Cache;

/**
 * Adaptador para cache basado en archivos.
 */
class DirectoryCache implements CacheInterface
{
    /**
     * Directorio en el sistema de archivos.
     * @var string 
     */
    protected $_cacheDir = 'cache';
    
    /**
     * Constructor
     * @param string $cacheDir Directorio en el sistema de archivos.
     */
    public function __construct($cacheDir = '')
    {
        if ($cacheDir !== '') {
            if (!is_dir($cacheDir)) {
                throw new Exception('The specified cache directory is invalid.'); 
            }
            $this->_cacheDir = $cacheDir;
        }
    }
    
    /**
     * Establece un par clave-valor y adicionalmente su tiempo de expiración.
     * @param string $key Clave
     * @param string $data Valor
     * @param int $expirationtime Tiempo de expiración
     */
    public function set($key, $data, $expirationtime=0)
    {
        $cacheFile = $this->getCacheFile($key);
        if (!file_put_contents($cacheFile, serialize($data))) {
            throw new Exception('Error saving data with the key ' . $key . ' to the cache file.');
        }
        return $this;
    }
    
   /**
     * Obtener valor de una clave.
     * @param string $key
     */
    public function get($key)
    {
        if ($this->exists($key)) {
            $cacheFile = $this->getCacheFile($key);
            if (!$data = unserialize(file_get_contents($cacheFile))) {
                throw new Exception('Error reading data with the key ' . $key . ' from the cache file.');
            }
            return $data;
        }
        return null;
    }
    
    /**
     * Borrar una clave
     * @param string $key
     */
    public function delete($key)
    {
        if ($this->exists($key)) {
            $cacheFile = $this->getCacheFile($key);
            if (!unlink($cacheFile)) {
                throw new Exception('Error deleting the file cache with key ' . $key);
            }
            return true;
        }
        return false;
    }
    
    /**
     * Verifica si el archivo de cache especifico existe.
     * @param $key
     */
    public function exists($key)
    {
        $cacheFile = $this->getCacheFile($key);
        return file_exists($cacheFile);
    }
    
    /**
     * Obtiene un especifico archivo de cache
     * @param string $key Clave en el cache
     */
    protected function getCacheFile($key)
    {
        return $this->_cacheDir . DIRECTORY_SEPARATOR . strtolower($key) . '.cache';
    } 
    
     /**
     * Cerrar la conexión al cache
     */
    public function close(){
        return true;
    }
    
    /**
     * Colector de basura.
     * @param string $maxlifetime
     */
    public function gc($maxlifetime){
        return true;
    }
}


